/**
 * @file memory.h
 * @author lcz (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2022-10-26
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#ifndef MEMORY_H
#define MEMORY_H

#include "comm/types.h"
#include "tools/bitmap.h"
#include "ipc/mutex.h"
#include "comm/boot_info.h"
#include "cpu/mmu.h"

#define MEM_EXT_START (1024*1024)
// 后面对虚拟页进行初始化时大小也是4k
#define MEM_PAGE_SIZE 4096
#define MEM_EBDA_START 0x80000
#define MEMORY_TASK_BASE 0x80000000
//#define MEM_EXT_END 0x80000000 // 太大，太耗时了
// 然而实际跑起来还是有点小慢，我在改小一些，修改为原来的4/1,现在内核0-32M（0x200 0000）才是一一映射的关系
// 去掉打印速度还可以，改回来
#define MEM_EXT_END (127 * 1024 * 1024)

#define MEM_TASK_STACK_TOP 0xE0000000
// 100k
#define MEM_TASK_STACK_SIZE (100 * 1024)
// 16k
#define MEM_TASK_ARG_SIZE (MEM_PAGE_SIZE *4)

typedef struct _addr_alloc_t {
    mutex_t mutex; // 地址分配互斥信号量
    bitmap_t bitmap; // 辅助分配用的位图
    uint32_t start;  // 起始地址
    uint32_t size;   // 地址大小
    uint32_t page_size; // 页大小
} addr_alloc_t;

/**
 * @brief 定义线性地址，虚拟地址结构
 */
typedef struct _memory_map_t{
    void *vstart;  //// 虚拟地址 虚拟地址（线性地址，逻辑地址）开始地址
    void *vend;    // 	虚拟地址结束
    void *pstart;  // 物理地址
    uint32_t perm; // 特权相关,属性
} memory_map_t;

    void
    memory_init(boot_info_t *boot_info);
void addr_free_page(addr_alloc_t *alloc, uint32_t addr, int page_count);
uint32_t addr_alloc_page(addr_alloc_t *alloc, int page_count);

uint32_t memory_create_uvm(void);

int memory_alloc_page_for(uint32_t addr, uint32_t size, int perm);

uint32_t memory_alloc_page(void);
void memory_free_page(uint32_t addr);
int memory_create_map(pde_t *page_dir, uint32_t vaddr, uint32_t paddr, int count, uint32_t perm);
void memory_destory_uvm(uint32_t page_dir);
uint32_t memory_copy_uvm(uint32_t page_dir);
int memory_alloc_for_page_dir(uint32_t page_dir, uint32_t vaddr, uint32_t size, int perm);

// 放回虚拟地址在页表中对应的物理地址
uint32_t memory_get_paddr(uint32_t page_dir, uint32_t vaddr);

int memory_copy_uvm_data(uint32_t to, uint32_t page_dir, uint32_t from, uint32_t size);

char *sys_sbrk(int incr);

#endif






